﻿namespace Pub.Class
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.IO.Compression;
    using System.Runtime.InteropServices;
    using System.Security.Cryptography;
    using System.Text;
    using System.Web;

    public class FileDirectory
    {
        public static int APIDelete(string path)
        {
            SHFILEOPSTRUCT shfileopstruct;
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("DirectoryPath");
            }
            shfileopstruct = new SHFILEOPSTRUCT {
                wFunc = wFunc.FO_DELETE,
                pFrom = path + "\0",
                fFlags = (FILEOP_FLAGS.FOF_NOERRORUI | FILEOP_FLAGS.FOF_SILENT | FILEOP_FLAGS.FOF_NOCONFIRMATION) & ~FILEOP_FLAGS.FOF_ALLOWUNDO,
                fAnyOperationsAborted = false
            };
            return SHFileOperation(ref shfileopstruct);
        }

        public static void DirectoryCopy(string Source, string Destination, bool Recursive = true, CopyOptions Options = CopyOptions.CopyIfNewer)
        {
            if (string.IsNullOrEmpty(Source))
            {
                throw new ArgumentNullException("Source");
            }
            if (string.IsNullOrEmpty(Destination))
            {
                throw new ArgumentNullException("Destination");
            }
            if (!DirectoryExists(Source))
            {
                throw new ArgumentException("Source directory does not exist");
            }
            DirectoryInfo info = new DirectoryInfo(Source);
            DirectoryInfo info2 = new DirectoryInfo(Destination);
            DirectoryCreate(Destination);
            foreach (FileInfo info3 in FileList(Source, false))
            {
                if (Options == CopyOptions.CopyAlways)
                {
                    info3.CopyTo(Path.Combine(info2.FullName, info3.Name), true);
                }
                else if (Options == CopyOptions.CopyIfNewer)
                {
                    if (FileExists(Path.Combine(info2.FullName, info3.Name)))
                    {
                        FileInfo info4 = new FileInfo(Path.Combine(info2.FullName, info3.Name));
                        if (info4.LastWriteTime.CompareTo(info3.LastWriteTime) < 0)
                        {
                            info3.CopyTo(Path.Combine(info2.FullName, info3.Name), true);
                        }
                    }
                    else
                    {
                        info3.CopyTo(Path.Combine(info2.FullName, info3.Name), true);
                    }
                }
                else if (Options == CopyOptions.DoNotOverwrite)
                {
                    info3.CopyTo(Path.Combine(info2.FullName, info3.Name), false);
                }
            }
            if (Recursive)
            {
                foreach (DirectoryInfo info5 in DirectoryList(info.FullName))
                {
                    DirectoryCopy(info5.FullName, Path.Combine(info2.FullName, info5.Name), Recursive, Options);
                }
            }
        }

        public static bool DirectoryCreate(string filePath)
        {
            return MakeSureDirectoryPathExists(filePath.TrimEnd(new char[] { '\\' }) + @"\");
        }

        public static void DirectoryDelete(string DirectoryPath)
        {
            if (string.IsNullOrEmpty(DirectoryPath))
            {
                throw new ArgumentNullException("DirectoryPath");
            }
            if (DirectoryExists(DirectoryPath))
            {
                Directory.Delete(DirectoryPath, true);
            }
        }

        public static bool DirectoryExists(string folderPath)
        {
            return Directory.Exists(folderPath);
        }

        public static DateTime DirectoryLastModified(string folderPath)
        {
            DirectoryInfo info = new DirectoryInfo(folderPath);
            return info.LastWriteTime;
        }

        public static List<DirectoryInfo> DirectoryList(string DirectoryPath)
        {
            if (string.IsNullOrEmpty(DirectoryPath))
            {
                throw new ArgumentNullException("DirectoryPath");
            }
            List<DirectoryInfo> list = new List<DirectoryInfo>();
            if (DirectoryExists(DirectoryPath))
            {
                DirectoryInfo info = new DirectoryInfo(DirectoryPath);
                foreach (DirectoryInfo info2 in info.GetDirectories())
                {
                    list.Add(info2);
                }
            }
            return list;
        }

        public static long DirectorySize(string path)
        {
            long num = 0L;
            if (!DirectoryExists(path))
            {
                return 0L;
            }
            foreach (string str in Directory.GetFiles(path))
            {
                num += new FileInfo(str).Length;
            }
            foreach (string str2 in Directory.GetDirectories(path))
            {
                num += DirectorySize(str2);
            }
            return num;
        }

        public static void DirectoryVirtualCreate(string filePath)
        {
            string[] strArray = filePath.Split(new string[] { "/" }, StringSplitOptions.None);
            string path = strArray[0];
            for (int i = 1; i < strArray.Length; i++)
            {
                path = path + "/" + strArray[i];
                string str2 = HttpContext.Current.Server.MapPath(path);
                if (!Directory.Exists(str2))
                {
                    Directory.CreateDirectory(str2);
                }
            }
        }

        public static bool FileCompare(string FileName1, string FileName2)
        {
            if (string.IsNullOrEmpty(FileName1))
            {
                throw new ArgumentNullException("FileName1");
            }
            if (string.IsNullOrEmpty(FileName2))
            {
                throw new ArgumentNullException("FileName2");
            }
            if (!FileExists(FileName1))
            {
                throw new ArgumentException("FileName1 does not exist");
            }
            if (!FileExists(FileName2))
            {
                throw new ArgumentException("FileName2 does not exist");
            }
            FileInfo info = new FileInfo(FileName1);
            FileInfo info2 = new FileInfo(FileName2);
            if (info.Length != info2.Length)
            {
                return false;
            }
            string str = Log.ReadAll(FileName1, Encoding.Default);
            string str2 = Log.ReadAll(FileName2, Encoding.Default);
            if (!str.Equals(str2))
            {
                return false;
            }
            return true;
        }

        public static bool FileCopy(string sourceFileName, string destFileName, bool overwrite)
        {
            if (!File.Exists(sourceFileName))
            {
                return false;
            }
            if (!overwrite && File.Exists(destFileName))
            {
                return false;
            }
            try
            {
                File.Copy(sourceFileName, destFileName, true);
            }
            catch
            {
                return false;
            }
            return true;
        }

        public static void FileDelete(string filePath)
        {
            if (FileExists(filePath))
            {
                File.Delete(filePath);
            }
        }

        public static void FileDeleteAll(string path)
        {
            if (DirectoryExists(path))
            {
                FileInfo[] files = new DirectoryInfo(path).GetFiles();
                for (int i = 0; i < files.Length; i++)
                {
                    files[i].Delete();
                }
            }
        }

        public static void FileDeleteNewerThan(string Directory, DateTime CompareDate, bool Recursive = false)
        {
            if (string.IsNullOrEmpty(Directory))
            {
                throw new ArgumentNullException("Directory");
            }
            foreach (FileInfo info in FileList(Directory, Recursive))
            {
                if (info.LastWriteTime > CompareDate)
                {
                    FileDelete(info.FullName);
                }
            }
        }

        public static void FileDeleteOlderThan(string Directory, DateTime CompareDate, bool Recursive = false)
        {
            if (string.IsNullOrEmpty(Directory))
            {
                throw new ArgumentNullException("Directory");
            }
            foreach (FileInfo info in FileList(Directory, Recursive))
            {
                if (info.LastWriteTime < CompareDate)
                {
                    FileDelete(info.FullName);
                }
            }
        }

        public static Encoding FileEncoding(string fileName)
        {
            if (!FileExists(fileName))
            {
                return null;
            }
            try
            {
                FileStream input = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                BinaryReader reader = new BinaryReader(input, Encoding.Default);
                byte[] buffer = reader.ReadBytes(3);
                reader.Close();
                input.Close();
                input.Dispose();
                if (buffer[0] >= 0xef)
                {
                    if (((buffer[0] == 0xef) && (buffer[1] == 0xbb)) && (buffer[2] == 0xbf))
                    {
                        return Encoding.UTF8;
                    }
                    if ((buffer[0] == 0xfe) && (buffer[1] == 0xff))
                    {
                        return Encoding.BigEndianUnicode;
                    }
                    if ((buffer[0] == 0xff) && (buffer[1] == 0xfe))
                    {
                        return Encoding.Unicode;
                    }
                    return Encoding.Default;
                }
                return Encoding.Default;
            }
            catch
            {
                return Encoding.Default;
            }
        }

        public static bool FileExists(string filename)
        {
            return File.Exists(filename);
        }

        public static DateTime FileLastModified(string filePath)
        {
            if (!FileExists(filePath))
            {
                throw new ArgumentException("filePath does not exist");
            }
            FileInfo info = new FileInfo(filePath);
            return info.LastWriteTime;
        }

        public static IList<string> FileList(string path)
        {
            IList<string> list = new List<string>();
            FileInfo[] files = new DirectoryInfo(path).GetFiles();
            for (int i = 0; i < files.Length; i++)
            {
                list.Add(files[i].Name);
            }
            return list;
        }

        public static List<FileInfo> FileList(string DirectoryPath, bool Recursive = false)
        {
            if (string.IsNullOrEmpty(DirectoryPath))
            {
                throw new ArgumentNullException("DirectoryPath");
            }
            List<FileInfo> list = new List<FileInfo>();
            if (DirectoryExists(DirectoryPath))
            {
                DirectoryInfo info = new DirectoryInfo(DirectoryPath);
                list.AddRange(info.GetFiles());
                if (!Recursive)
                {
                    return list;
                }
                foreach (DirectoryInfo info2 in info.GetDirectories())
                {
                    list.AddRange(FileList(info2.FullName, true));
                }
            }
            return list;
        }

        public static void FileList(string path, ref IList<string> fileList, string delStr)
        {
            if (delStr.Equals(""))
            {
                delStr = path;
            }
            delStr = delStr.Substring(delStr.Length - 1).Equals(@"\") ? delStr : (delStr + @"\");
            foreach (string str in Directory.GetFiles(path))
            {
                fileList.Add(str.Replace(delStr, ""));
            }
            foreach (string str2 in Directory.GetDirectories(path))
            {
                FileList(str2, ref fileList, delStr);
            }
        }

        public static void FileRename(string FileName, string NewFileName)
        {
            if (string.IsNullOrEmpty(FileName))
            {
                throw new ArgumentNullException("FileName");
            }
            if (string.IsNullOrEmpty(NewFileName))
            {
                throw new ArgumentNullException("NewFileName");
            }
            if (!FileExists(FileName))
            {
                throw new ArgumentException("FileName does not exist");
            }
            File.Move(FileName, NewFileName);
        }

        public static long FileSize(string path)
        {
            if (!FileExists(path))
            {
                return 0L;
            }
            return new FileInfo(path).Length;
        }

        public static string GetFileContent(string filePath)
        {
            if (!FileExists(filePath))
            {
                return string.Empty;
            }
            using (TextReader reader = new StreamReader(filePath))
            {
                return reader.ReadToEnd();
            }
        }

        public static void GZipCompress(string inFilename, string outFilename)
        {
            if (FileExists(inFilename))
            {
                FileStream stream = File.OpenRead(inFilename);
                FileStream stream2 = File.Create(outFilename);
                GZipStream stream3 = new GZipStream(stream2, CompressionMode.Compress);
                for (int i = stream.ReadByte(); i != -1; i = stream.ReadByte())
                {
                    stream3.WriteByte((byte) i);
                }
                stream.Close();
                stream3.Close();
                stream2.Close();
            }
        }

        public static void GZipDecompress(string inFileName, string outFileName)
        {
            if (FileExists(inFileName))
            {
                FileStream stream = File.OpenRead(inFileName);
                FileStream stream2 = File.Create(outFileName);
                GZipStream stream3 = new GZipStream(stream, CompressionMode.Decompress);
                for (int i = stream3.ReadByte(); i != -1; i = stream3.ReadByte())
                {
                    stream2.WriteByte((byte) i);
                }
                stream2.Close();
                stream3.Close();
                stream.Close();
            }
        }

        public static string HashCRC32(string fileName)
        {
            string str = string.Empty;
            if (!File.Exists(fileName))
            {
                return str;
            }
            using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                CRC32 crc = new CRC32();
                byte[] buffer = crc.ComputeHash(stream);
                crc.Clear();
                StringBuilder builder = new StringBuilder();
                for (int i = 0; i < buffer.Length; i++)
                {
                    builder.Append(buffer[i].ToString("x2"));
                }
                return builder.ToString();
            }
        }

        public static string HashMD5(string fileName)
        {
            string str = string.Empty;
            if (!File.Exists(fileName))
            {
                return str;
            }
            using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                MD5 md = MD5.Create();
                byte[] buffer = md.ComputeHash(stream);
                md.Clear();
                StringBuilder builder = new StringBuilder();
                for (int i = 0; i < buffer.Length; i++)
                {
                    builder.Append(buffer[i].ToString("x2"));
                }
                return builder.ToString();
            }
        }

        public static string HashSHA1(string fileName)
        {
            string str = string.Empty;
            if (!File.Exists(fileName))
            {
                return str;
            }
            using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                SHA1 sha = SHA1.Create();
                byte[] buffer = sha.ComputeHash(stream);
                sha.Clear();
                StringBuilder builder = new StringBuilder();
                for (int i = 0; i < buffer.Length; i++)
                {
                    builder.Append(buffer[i].ToString("x2"));
                }
                return builder.ToString();
            }
        }

        [DllImport("dbgHelp", SetLastError=true)]
        private static extern bool MakeSureDirectoryPathExists(string name);
        [DllImport("shell32.dll")]
        private static extern int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp);

        private enum FILEOP_FLAGS
        {
            FOF_ALLOWUNDO = 0x40,
            FOF_CONFIRMMOUSE = 2,
            FOF_FILESONLY = 0x80,
            FOF_MULTIDESTFILES = 1,
            FOF_NOCONFIRMATION = 0x10,
            FOF_NOCONFIRMMKDIR = 0x200,
            FOF_NOCOPYSECURITYATTRIBS = 0x800,
            FOF_NOERRORUI = 0x400,
            FOF_NORECURSION = 0x1000,
            FOF_RENAMEONCOLLISION = 8,
            FOF_SILENT = 0x44,
            FOF_SIMPLEPROGRESS = 0x100,
            FOF_WANTMAPPINGHANDLE = 0x20
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct SHFILEOPSTRUCT
        {
            public IntPtr hwnd;
            public Pub.Class.FileDirectory.wFunc wFunc;
            public string pFrom;
            public string pTo;
            public FileDirectory.FILEOP_FLAGS fFlags;
            public bool fAnyOperationsAborted;
            public IntPtr hNameMappings;
            public string lpszProgressTitle;
        }

        private enum wFunc
        {
            FO_COPY = 2,
            FO_DELETE = 3,
            FO_MOVE = 1,
            FO_RENAME = 4
        }
    }
}

